function RMove(hintId) {
	this.isActing = false;
	this.selectedObject= null;
	this.selectedCell=null;
	this.action = "";
	this.dx = 0;
	this.dy = 0;
	this.tolerance = 5;
	this.div = document.createElement("div");
	document.body.insertBefore(this.div);
	with (this.div.style) {
		display = "none";
		border = "1px dotted red";
		fontSize = 1;
		margin = 0;
		padding = 0;
		position = "absolute";
		posLeft = 0;
		posTop = 0;
		posWidth = 0;
		posHeight = 0;
		zIndex = 0;
		filter="alpha(opacity=50)";
	}
	this.objects = new Array();
	this.zIndex = new Array();
	this.hint = $(hintId);
}

RMove.prototype = {
	addObject: function(objId) {
		var o = $(objId);
		if (o==null) return;
		this.objects[this.objects.length] = o;
		o.style.fontSize=1;
		o.style.margin=0;
		o.style.padding=0;
		o.style.position="absolute";
		o.style.overflow="hidden";
		o.style
		if (this.zIndex.length > 0 && o.style.zIndex <= this.zIndex[this.zIndex.length-1])
			o.style.zIndex = this.zIndex[this.zIndex.length-1]+1;
		this.zIndex[this.zIndex.length] = o.style.zIndex;
		if (o.style.zIndex >= this.div.style.zIndex)
			this.div.style.zIndex = o.style.zIndex + 1;
	},
	setEnabled: function(enabled) {
		if (enabled) {
			this.document_onmousemove = document.onmousemove;
			this.document_onclick = document.onclick;
			document.onmousemove = this.mouseMove.bind(this);
			document.onclick = this.mouseClick.bind(this);
		} else {
			document.onmousemove = this.document_onmousemove;
			document.onclick = this.document_onclick;
		}
	},
	testSelection: function (o) {
		var result = false;
		var left=parseInt(o.style.posLeft);
		var top=parseInt(o.style.posTop);
		var right=parseInt(o.style.posLeft)+parseInt(o.style.width);
		var bottom=parseInt(o.style.posTop)+parseInt(o.style.height);
		if (event.clientX <= left+this.tolerance && event.clientX >= left) {
			if (event.clientY <= top+this.tolerance && event.clientY >= top) {
				this.selectedObject = o;
				this.action = "NW-resize";
				result = true;
			} else if (event.clientY <= bottom && event.clientY >= bottom-this.tolerance) {
				this.selectedObject = o;
				this.action = "SW-resize";
				result = true;
			} else if (event.clientY <= bottom-this.tolerance && event.clientY >= top+this.tolerance) {
				this.selectedObject = o;
				this.action = "W-resize";
				result = true;
			}
		} else if (event.clientX <= right && event.clientX >= right-this.tolerance) {
			if (event.clientY<=top+this.tolerance && event.clientY>=top) {
				this.selectedObject = o;
				this.action = "NE-resize";
				result = true;
			} else if (event.clientY <=bottom && event.clientY >= bottom-this.tolerance) {
				this.selectedObject = o;
				this.action = "SE-resize";
				result = true;
			} else if (event.clientY <= bottom-this.tolerance && event.clientY >= top+this.tolerance) {
				this.selectedObject = o;
				this.action = "E-resize";
				result = true;
			}
		} else if (event.clientY <= top+this.tolerance && event.clientY >= top) {
			if (event.clientX <= left+this.tolerance && event.clientX >= left) {
				this.selectedObject = o;
				this.action = "NW-resize";
				result = true;
			} else if (event.clientX <= right && event.clientX >= right-this.tolerance) {
				this.selectedObject = o;
				this.action = "NE-resize";
				result = true;
			} else if (event.clientX <= right-this.tolerance && event.clientX >= left+this.tolerance) {
				this.selectedObject = o;
				this.action = "N-resize";
				result = true;
			}
		} else if (event.clientY <= bottom && event.clientY >= bottom-this.tolerance) {
			if (event.clientX <= left+this.tolerance && event.clientX >= left) {
				this.selectedObject = o;
				this.action = "SW-resize";
				result = true;
			} else if (event.clientX <= right && event.clientX >= right-this.tolerance) {
				this.selectedObject = o;
				this.action = "SE-resize";
				result = true;
			} else if (event.clientX <= right-this.tolerance && event.clientX >= left+this.tolerance) {
				this.selectedObject = o;
				this.action = "S-resize";
				result = true;
			}
		} else if (event.clientX > left+this.tolerance && event.clientX < right-this.tolerance 
			&& event.clientY > top+this.tolerance && event.clientY < bottom-this.tolerance) {
			this.selectedObject = o;
			this.action = "move";
			result = true;
		}
		return result;
	},
	testCellResize: function() {
		var es = this.selectedObject.getElementsByTagName("TABLE");
		this.hint.innerText=es.length;
		for (var i=0; i<es.length; ++i) {
			var row = es[i].rows[0];		
			if (row == null) return;
			if (row.cells.length==1) return; // only one column, no resize available
			for (var j=0; j<row.cells.length-1; ++j) {
				var c = row.cells[j];
				var x = absLeft(c)+c.offsetWidth;
				var y0 = absTop(c);
				var y1 = y0 + c.offsetHeight;
				if (event.clientX>=x-1 &&  event.clientX<=x+1 && event.clientY>=y0 && event.clientY<=y1) {
					this.selectedCell=c;
					this.action="E-resize";
					return true;
				}
			}
		}
		return false;
	},
	mouseMove: function() {
		if (this.isActing) {
			if (this.selectedCell != null) {
				var w = event.clientX - this.div.style.posLeft;
				if (w <= 1) w = 1;
				this.div.style.posWidth = w;
			} else { // handle selectedObject
				if (this.action == "move") {
		  		this.div.style.posLeft = event.clientX - dx;
		  		this.div.style.posTop = event.clientY - dy;
				} else {
					var left=parseInt(this.selectedObject.style.posLeft);
					var top=parseInt(this.selectedObject.style.posTop);
					var right=parseInt(this.selectedObject.style.posLeft)+parseInt(this.selectedObject.style.width);
					var bottom=parseInt(this.selectedObject.style.posTop)+parseInt(this.selectedObject.style.height);
					if (this.action == "W-resize" || this.action == "NW-resize" || this.action == "SW-resize") {
						var w = right-event.clientX;
						if (w < this.tolerance*2) w = this.tolerance*2;
						this.div.style.width = w;
						this.div.style.posLeft = right-w;
					} 
					if (this.action == "N-resize" || this.action == "NW-resize" || this.action == "NE-resize") {
						var h = bottom-event.clientY;
						if (h < this.tolerance*2) h = this.tolerance*2;
						this.div.style.posHeight = h;
						this.div.style.posTop = bottom-h;
					} 
					if (this.action == "E-resize" || this.action == "NE-resize" || this.action == "SE-resize") {
						var w = event.clientX-left;
						if (w < this.tolerance*2) w = this.tolerance*2;
						this.div.style.width = w;
					} 
					if (this.action == "S-resize" || this.action == "SW-resize" || this.action == "SE-resize") {
						var h = event.clientY-top;
						if (h < this.tolerance*2) h = this.tolerance*2;
						this.div.style.height = h;
					}
				}
			}
		} else {
			this.selectedObject = null;
			this.selectedCell = null;
			this.action = "";
			for (var i = this.objects.length-1; i>=0; --i) {
				if (this.testSelection(this.objects[i])) {
					if (this.testCellResize()) {
						this.selectedObject.style.cursor = this.action;
						this.div.style.height=this.selectedCell.offsetHeight;
						this.div.style.width=this.selectedCell.offsetWidth;
						this.div.style.posLeft=absLeft(this.selectedCell);
						this.div.style.posTop=absTop(this.selectedCell);
						this.div.style.cursor=this.action;
					} else {
						this.selectedObject.style.cursor = this.action;
						this.div.style.height=this.selectedObject.style.height;
						this.div.style.width=this.selectedObject.style.width;
						this.div.style.posLeft=this.selectedObject.style.posLeft;
						this.div.style.posTop=this.selectedObject.style.posTop;
						this.div.style.cursor=this.action;
					}
					break;
				}
				if (this.selectedObject != null)
					this.selectedObject.style.cursor = "auto";
			}
		}
		if (this.hint != null) {
			var s = "(x="+event.clientX + ",y=" + event.clientY + ")";
			if (this.selectedCell != null)
				s += " " + this.action + " cell (x="+this.div.style.posLeft+",y="+this.div.style.posTop
					+",w="+this.div.style.posWidth+",h="+this.div.style.posHeight+")";
			else if (this.selectedObject != null)
				s += " " + this.action + " (x="+this.div.style.posLeft+",y="+this.div.style.posTop
					+",w="+this.div.style.posWidth+",h="+this.div.style.posHeight+")";
			this.hint.innerText=s;
		}
	},
	mouseClick: function() {
		if (this.isActing) {
			this.isActing=false;
			if (this.selectedCell != null) {
				this.selectedCell.width=this.div.style.posWidth;
				this.div.style.display="none";
			} else { // handle selectedObject			
					this.selectedObject.style.posLeft=this.div.style.posLeft;
					this.selectedObject.style.posTop=this.div.style.posTop;
					this.selectedObject.style.width=this.div.style.width;
					this.selectedObject.style.height=this.div.style.height;
					this.selectedObject.style.cursor="auto";
					this.div.style.display="none";
					// put the object in the last of the objects array
					var i=this.objects.indexOf(this.selectedObject);
					this.objects[i] = this.objects[this.objects.length-1];
					this.objects[this.objects.length-1].style.zIndex = this.zIndex[i];
					this.objects[this.objects.length-1] = this.selectedObject;
					this.selectedObject.style.zIndex = this.zIndex[this.zIndex.length-1];
			}
		} else if (this.selectedCell != null) {
			this.isActing=true;
			this.div.style.display="block";
		} else if (this.selectedObject != null) {
			this.isActing=true;
			this.div.style.display="block";
			dx = event.clientX - this.div.style.posLeft;
			dy = event.clientY - this.div.style.posTop;
		}
	},
	getSettings: function() {
		// data structure:
		// sa: array of set
		// set: id, posLeft, posTop, posWidth, posHeight, cells: array of cell
		// cell: id, offsetWidth
		var sa = new Array();
		for (var i=0; i<this.objects.length; ++i) {
			var o = this.objects[i];
			var set = new Object();
			sa[sa.length]=set;
			set.id = o.id;
			set.posLeft = o.style.posLeft;
			set.posTop = o.style.posTop;
			set.posWidth = o.style.posWidth;
			set.posHeight = o.style.posHeight;
			set.cells = new Array();
			var es = o.getElementsByTagName("TD");
			for (var j = 0; j < es.length; ++j) {
				if (isDefined(es[j].id) && es[j].id.length > 0) {
					var cell=new Object();
					set.cells[set.cells.length] = cell;
					cell.id = es[j].id;
					cell.offsetWidth = es[j].offsetWidth;
				}
			}
		}
		var b = new Buffalo("aaa", false);
		var call = new Buffalo.Call("aaa");
		call.addParameter(sa);
		var s = call.xml().replace('<burlap:call>', '<burlap:reply xmlns:burlap=\"http://www.amowa.net/buffalo/\">');
		s = s.replace('<method>aaa</method>', '');
		s = s.replace('</burlap:call>', '</burlap:reply>');
		return '<?xml version="1.0" encoding="utf-8"?>' + s;
	},
	setSettings: function(settingString) {
		var sa = new Buffalo.Reply(settingString).getResult();
		for (var i=0; i<sa.length; ++i) {
			var set=sa[i];
			var o=document.getElementById(set.id);
			if (o != null) {
				o.style.posLeft=set.posLeft;
				o.style.posTop=set.posTop;
				o.style.posWidth=set.posWidth;
				o.style.posHeight=set.posHeight;
				for (var j=0; j<set.cells.length; ++j) {
					var cell=set.cells[j];
					o=document.getElementById(cell.id);
					if (o!=null){
						try {o.width=cell.offsetWidth;} catch(e){}
					}
				}
			}
		}
	}
}
